Os Dados

[1]:

import pandas as pd

# reading csv file
BRdata = pd.read_csv("./PG_IMT/DadosEpidemia/CoVid19.csv")
BRdata.head()

[1]:
date country state city newDeaths deaths newCases totalCases deathsMS totalCasesMS deaths_per_100k_inhabitants totalCases_per_100k_inhabitants deaths_by_totalCases recovered suspects tests tests_per_100k_inhabitants
0 2020-02-25 Brazil SP TOTAL 0 0 1 1 0 0 0.0 0.00218 0.0 NaN NaN NaN NaN
1 2020-02-25 Brazil TOTAL TOTAL 0 0 1 1 0 0 0.0 0.00048 0.0 NaN NaN NaN NaN
2 2020-02-26 Brazil SP TOTAL 0 0 0 1 0 1 0.0 0.00218 0.0 NaN NaN NaN NaN
3 2020-02-26 Brazil TOTAL TOTAL 0 0 0 1 0 1 0.0 0.00048 0.0 NaN NaN NaN NaN
4 2020-02-27 Brazil SP TOTAL 0 0 0 1 0 1 0.0 0.00218 0.0 NaN NaN NaN NaN

Filtrando e limpando os dados

[2]:

is_SP =  BRdata['state']=='TOTAL'
SPdata = BRdata[is_SP]

# SPdata = SPdata.fillna(0)

SPLimpo = SPdata[SPdata.recovered.notnull()]
SPLimpo.head()

[2]:
date country state city newDeaths deaths newCases totalCases deathsMS totalCasesMS deaths_per_100k_inhabitants totalCases_per_100k_inhabitants deaths_by_totalCases recovered suspects tests tests_per_100k_inhabitants
321 2020-03-23 Brazil TOTAL TOTAL 9 34 358 1952 34 1891 0.01618 0.92887 0.01742 8.0 15867.0 NaN NaN
349 2020-03-24 Brazil TOTAL TOTAL 13 47 303 2255 46 2201 0.02237 1.07306 0.02084 20.0 17700.0 NaN NaN
377 2020-03-25 Brazil TOTAL TOTAL 12 59 311 2566 57 2433 0.02808 1.22105 0.02299 27.0 27227.0 NaN NaN
405 2020-03-26 Brazil TOTAL TOTAL 18 77 424 2990 77 2915 0.03664 1.42281 0.02575 42.0 48793.0 NaN NaN
433 2020-03-27 Brazil TOTAL TOTAL 16 93 486 3476 92 3417 0.04425 1.65408 0.02675 42.0 50684.0 NaN NaN
[3]:

from datetime import datetime

first_date = SPLimpo["date"].iloc[0]
first_date = datetime.fromisoformat(first_date)

SPsir = SPLimpo[["totalCases", "deaths", "recovered"]].to_numpy()

SPsir[:,0:]
SPI = SPsir[:,0]
auxM = SPsir[:,1]
SPM = auxM
auxR = SPsir[:,2]
SPR = auxR

Visualizando a evolução

[4]:

from bokeh.models   import Legend, ColumnDataSource, RangeTool, LinearAxis, Range1d
from bokeh.palettes import brewer, Inferno256
from bokeh.plotting import figure, show
from bokeh.layouts  import column
from bokeh.io       import output_notebook

output_notebook()

from datetime import timedelta

# Criando o vetor de tempo
t_num = range(len(SPM))
date_vec = [ first_date + timedelta(days=k) for k in t_num]


# Criando a figura
p = figure(
    tools="hover",
    title="Evolução do COVID",
    x_axis_type='datetime',
    y_axis_type="log",
    plot_width=650,
    plot_height=500
)

# Incluindo os dados de mortes
p.line(
    date_vec, SPM,
    legend_label="Mortes",
    line_width=4,
    line_cap="round",
    color="#de425b"
)

# Incluindo os dados de infectados
p.line(
    date_vec, SPI,
    legend_label="Infectados",
    line_width=4,
    line_cap="round",
    color="#ffd885"
)

# Incluindo os dados de recuperados
p.line(
    date_vec, SPR,
    legend_label="Removidos",
    line_width=4,
    line_cap="round",
    color="#99d594"
)


p.grid.grid_line_alpha = 0
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.yaxis.axis_label = "Indivíduos"
p.xaxis.axis_label = "Dias"
p.legend.click_policy="hide"
p.legend.location = "bottom_right"

show(p)

Loading BokehJS ...

Análise de um modelo com \(\beta\) variável no tempo

Uma outra forma de abordar a modelagme de dados é assumindo que a taxa de transmissão \(\beta\) é variante no tempo. Vamos, neste sentido, utilizar a abordagem elaborada por Mark Pollicott, Hao Wang & Howard (Howie) Weiss em 2012 - Extracting the time-dependent transmission rate from infection data via solution of an inverse ODE problem

Reescrevendo o conjunto de equações diferenciais que caracteriza o modelo é descrito abaixo. No modelo $:nbsphinx-math:beta`(t) - :nbsphinx-math:text{representa a taxa de transmissão ou taxa efetiva de contato}` $ e \(r - \text{a taxa de remoção ou recuperação.}\)

\[\begin{split}\begin{split} \frac{dS(t)}{dt} & = -\mathbf{\beta(t)} S(t) I(t) \\ \frac{dI(t)}{dt} & = \mathbf{\beta(t)} S(t) I(t) - rI(t) \\ \frac{dR(t)}{dt} & = r I(t) \end{split}\end{split}\]

Gostaríamos de identificar quais parâmetros \(\beta(t)\) e \(r\) resultam num melhor ajuste do modelo para os dados de S,I e R

Proposta de algoritmo para extração do \(\beta(t)\) a partir dos dados

  1. Interpolar os dados para suvizar eventuais variações gerando uma função \(f(t)\)
  2. Verificar a seguinte condição: \(\frac{f'(t)}{f(t)}>-r\). Neste algoritmo a taza de romação \(r\) é considerada constante.
  3. Determinando a função \(p(t) = \frac{f''(t)f(t)-f'^2(t)}{f(t)(f'(t)+rf(t))}\).
  4. Escolhendo um valor inicial para \(\beta(0)\) e determinando a integral \(P(t) = \int_0^t p(\tau) d\tau\).
  5. Verificar a seguinte condição: \(\beta(0) <\frac{1}{\int_0^t e^{P(s)}f(s) ds}\).
  6. O parâmetro \(\mathbf{\beta(t)}\) pode ser calculado por: \(\beta(t) = \frac{1}{\frac{e^{-P(t)}}{\beta(0)}-e^{-P(t)}\int_0^t e^{P(s)}f(s) ds}\).

1) Interpolar os dados para suvizar eventuais variações gerando uma função \(f(t)\)

[5]:

import numpy as np
from scipy.interpolate import Rbf, UnivariateSpline

# Generating weights for polynomial function with degree =2
weights = np.polyfit(t_num, SPI, 2)
rbf = Rbf(t_num, SPI, function='gaussian')
spline = UnivariateSpline(t_num, SPI)
print(weights)


# Generating model with the given weights
model = np.poly1d(weights)

t_sim = np.linspace(t_num[0], t_num[-1], 100)

# Prediction on validation set
pred = model(t_sim)
pred_rbf = rbf(t_sim)
pred_spline = spline(t_sim)

# We will plot the graph for 70 observations only

# Criando a figura
p = figure(
    tools="hover",
    title="Dados interpolados",
    x_axis_type='datetime',
#     y_axis_type="log",
    plot_width=650,
    plot_height=500
)

# Incluindo os dados de mortes
p.line(
    t_num, SPI,
    legend_label="Medidas",
    line_width=4,
    line_cap="round",
    color="#de425b"
)

# Incluindo os dados de infectados
p.line(
    t_sim, pred,
    legend_label="Interpolação",
    line_width=4,
    line_cap="round",
    color="#1e88e5"
)

p.line(
    t_sim, pred_rbf,
    legend_label="Interpolação - RBF",
    line_width=3,
    line_dash="dashed",
    line_cap="round",
    color="#512da8"
)

p.line(
    t_sim, pred_spline,
    legend_label="Interpolação - Spline",
    line_width=3,
    line_dash="dashed",
    line_cap="round",
    color="#00796b"
)

p.grid.grid_line_alpha = 0
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.yaxis.axis_label = "Indivíduos"
p.xaxis.axis_label = "Dias"
p.legend.click_policy="hide"
p.legend.location = "bottom_right"

show(p)


[  67.47775863 -501.31086778 4785.98379386]